#include "ThreadPool.h"
#include "Task.h"
#include <iostream>

using ULONG = unsigned long long;
class PrintTask : public Task {
public:
  explicit PrintTask(int id) : id_(id) {}
  Any run() override {
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "Task " << id_ << " executed\n";
    return {};
  }

private:
  int id_;
};

class CountSum : public Task {
public:
  CountSum(ULONG begin, ULONG end): begin_(begin), end_(end){}
  Any run() {
    std::cout << __PRETTY_FUNCTION__ << " tid:" << std::this_thread::get_id() << " CountSum开始"<< "\n";
    ULONG sum{};
    std::this_thread::sleep_for(std::chrono::seconds(3));
    for (ULONG i = begin_; i != end_ + 1; i++) {
      sum += i;
    }
    std::cout << __PRETTY_FUNCTION__ << " tid:" << std::this_thread::get_id() << " CountSum结束"<< "\n";
    return sum;
  };
private:
  ULONG begin_{};
  ULONG end_{};
};

int main() {
  {
    ThreadPool pool; // ThreadPool对象析构后, 如何回收线程资源

    pool.setMode(PoolMode::MODE_CACHED);
    pool.start(4);

    // Master-Slave
    
    auto res_sptr2 = pool.submitTask(std::make_shared<CountSum>(1, 100'000'000));
    auto res_sptr3 = pool.submitTask(std::make_shared<CountSum>(100'000'000, 200'000'000));
    auto res_sptr4 = pool.submitTask(std::make_shared<CountSum>(200'000'000, 300'000'000));

    pool.submitTask(std::make_shared<CountSum>(200'000'000, 300'000'000));
    pool.submitTask(std::make_shared<CountSum>(200'000'000, 300'000'000));
    pool.submitTask(std::make_shared<CountSum>(200'000'000, 300'000'000));
    pool.submitTask(std::make_shared<CountSum>(200'000'000, 300'000'000));
    
    ULONG sum4 = res_sptr4->get().cast_<ULONG>(); // 谁的 get() 先调用，就先在那儿阻塞，直到对应任务完成
    ULONG sum2 = res_sptr2->get().cast_<ULONG>();
    ULONG sum3 = res_sptr3->get().cast_<ULONG>();
    std::cout << "计算结果：" << sum2 + sum3 + sum4 << std::endl;
  }
  return 0;
}